package gwtappcontainer.server.apis.bigset;

import gwtappcontainer.server.apis.APIException;
import gwtappcontainer.server.apis.security.GateKeeper;
import gwtappcontainer.shared.apis.APIResponse;
import gwtappcontainer.shared.apis.APIResponse.Status;

import java.util.HashSet;

import javax.inject.Named;

import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.config.ApiMethod.HttpMethod;
import com.google.appengine.api.users.User;

@Api(name = "bigset", 
scopes = { "https://www.googleapis.com/auth/userinfo.email" }
)
public class BigSetAPI {
	
	final static long MAX_ELEMENTS_IN_SINGLE_SET = 50000;
	
	@ApiMethod(httpMethod  = HttpMethod.PUT, path="createnew")
	public APIResponse createNew(User user) {
		
		try {
			GateKeeper.ensureValidUser(user);
						
			long bigSetId = createNewBigSet(MAX_ELEMENTS_IN_SINGLE_SET);
						
			APIResponse resp = new APIResponse(Status.SUCCESS, bigSetId);
			return resp;
		} catch (Exception ex) {
			return new APIResponse(ex);
		}
	}
	
	//add only for unit testing purposes
	APIResponse createNewOnlyForTesting(User user, @Named("maxElementsInSet") long maxElementsInSet) {
		try {
			GateKeeper.ensureValidUser(user);
						
			long bigSetId = createNewBigSet(maxElementsInSet);
						
			APIResponse resp = new APIResponse(Status.SUCCESS, bigSetId);
			return resp;
		} catch (Exception ex) {
			return new APIResponse(ex);
		}
	}
	
	private long createNewBigSet(long maxElementsInSet) {
		
		if ((maxElementsInSet < 1) || (maxElementsInSet > MAX_ELEMENTS_IN_SINGLE_SET)) 
			throw new APIException(Status.ERROR_RESOURCE_INCORRECTLY_SPECIFIED, 
					"maxElementsInSet should be greater than 1 and less than " +
					MAX_ELEMENTS_IN_SINGLE_SET);
		
		long bigSetId = BigSetRepository.createNew(maxElementsInSet);
		
		return bigSetId;
	}
	
	@ApiMethod(httpMethod = HttpMethod.POST, path="addelement")
	public APIResponse addElement(@Named("bigSetId") long bigSetId, 
			@Named("element") long element, User user) {
		try {
			GateKeeper.ensureValidUser(user);
			
			BigSetRepository.addElement(bigSetId, element);
			
			APIResponse resp = new APIResponse(Status.SUCCESS, null);
			return resp;	
		} catch (Exception ex) {
			return new APIResponse(ex);
		}
	}
	
	@ApiMethod(httpMethod = HttpMethod.GET, path="getallelements")
	public APIResponse getAllElements(@Named("bigSetId") long bigSetId) {
		try {
			HashSet<Long> members = BigSetRepository.getAllElements(bigSetId);
			
			APIResponse response = new APIResponse(Status.SUCCESS, members);
			
			return response;
		} catch (Exception ex) {
			return new APIResponse(ex);
		}
	}
}
